package tom.spring.cloud.gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.config.EnableWebFlux;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;

/**
 * 基于配置的gateway, profiles: ratelimit1
 * http://localhost:8090/actuator/gateway/routes
 * 自定义KeyResolver 不使用spring-security
 * @author ZHUFEIFEI
 */
@Slf4j
@EnableWebFlux
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
                classes = {Gateway01Application.class, Gateway02Application.class})
})
public class Gateway03Application {

    public static void main(String[] args) {
        SpringApplication.run(Gateway03Application.class, args);
    }


    /**
     * 自定义keyResolver, 替换默认的PrincipalNameKeyResolver
     * @return
     */
    @Bean
    public KeyResolver keyResolver() {
        //自定义根据hostname客户端请求地址做key标识
//        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
        return exchange -> {
            //根据客户端地址做限制
            InetSocketAddress addr = exchange.getRequest().getRemoteAddress();
            if (addr != null) {
                log.info("use client address limit : {}", addr.getAddress());
                return Mono.just(addr.getHostString());
            }
            log.info("use request uri limit : {}", exchange.getRequest().getURI());
            //获取不到则根据接口名做限制
            return Mono.just(exchange.getRequest().getURI().toString());
        };
    }

    @EnableWebFluxSecurity
    class MyFluxSecurityConfig {

        @Bean
        public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
            //允许所有请求
            return http.authorizeExchange().anyExchange().permitAll().and().build();
        }

    }
}
